#pragma once

namespace gtl
{
	namespace patterns
	{

		namespace policy
		{
			struct polymorphism;
			struct no_polymorphism;
			struct empty;
		}

		template<class Concrete, class Type>
		struct memento;

		template<class Concrete>
		struct memento<Concrete, policy::polymorphism> : protected Concrete
		{
			virtual const Concrete& get_memento(void)		{ return static_cast<Concrete&>(*this); }
			virtual void set_memento(const Concrete& meme)	{ static_cast<Concrete&>(*this) = meme; }
		};

		template<class Concrete>
		struct memento<Concrete, policy::no_polymorphism> : protected Concrete
		{
			const Concrete& get_memento(void)				{ return static_cast<Concrete&>(*this); }
			void set_memento(const Concrete& meme)			{ static_cast<Concrete&>(*this) = meme; }
		};

	} // end namespace patterns
} // end namespace gtl